#include "connection.h"

Connection *Connection::instance = NULL;

Connection::Connection()
{
    if (!QSqlDatabase::isDriverAvailable (dbDriverStr))
    {
        qCritical() << dbDriverNotExistStr;
    }
    db = QSqlDatabase::addDatabase(dbDriverStr);

    bool flag = isDbExist ();
    db.setDatabaseName(dbFileNameStr);
    dbConnect();

    if (!flag)
    {
        if(!dbCreateInstance())
        {
            qCritical() << "Create Instance failed";
            exit(1);
        }
    }
}

Connection* Connection::getInstance()
{
    if (instance == NULL)
    {
        instance = new Connection;
    }
    return instance;
}

Connection::~Connection()
{
    dbDisconnect();
}

bool Connection::dbConnect()
{
    if (!db.open())
    {
        qWarning() << dbCannotOpenStr;
        return false;
    }
    qDebug() << dbConnectionOk;
    return db.isOpen();
}

bool Connection::dbDisconnect()
{
    qDebug() << dbDisconnectStr;
    db.close();
    if(!db.isOpen())
    {
        return true;
    }
    return false;
}

bool Connection::isDbExist()
{
    return dbFile.isFileExist(dbFileNameStr);
}

bool Connection::dbRemove()
{
    return dbFile.removeFile(dbFileNameStr);
}

bool Connection::dbCreateInstance()
{
    /* create and setup a progress bar. */
    WProgressBar *progress = WProgressBar::getInstance();
    progress->setText(dbCreateDatabase);
    progress->setMaximumStep(15);

    /* start progress. */
    progress->progress();

    /*
     *check if database is open
     */
    if(db.isOpen())
    {
        if(!createTable(progress,
                        "CREATE TABLE IF NOT EXISTS Genre "
                        "(Id INTEGER PRIMARY KEY AUTOINCREMENT,"
                        "Name VARCHAR2 unique)"
                        ))
            return false;

        if(!createTable(progress,
                        "CREATE TABLE IF NOT EXISTS Album "
                        "(Id INTEGER PRIMARY KEY AUTOINCREMENT,"
                        "Name VARCHAR2,"
                        "Year INT,"
                        "Cover VARCHAR2,"
                        "Heart BOOLEAN,"
                        "CONSTRAINT u_album UNIQUE (Name, Year, Cover)"
                        ")"
                        ))
            return false;

        if(!createTable(progress,
                        "CREATE TABLE IF NOT EXISTS Artist "
                        "(Id INTEGER PRIMARY KEY AUTOINCREMENT,"
                        "name VARCHAR2 unique,"
                        "Heart BOOLEAN"
                        ")"
                        ))
            return false;

        if(!createTable(progress,
                        "CREATE TABLE IF NOT EXISTS Track "
                        "(Id INTEGER PRIMARY KEY AUTOINCREMENT,"
                        "Name VARCHAR2,"
                        "Num INT,"
                        "Time VARCHAR2,"
                        "Lyrics VARCHAR2,"
                        "Score INT,"
                        "Recovery INTEGER,"
                        "Heart BOOLEAN,"
                        "Location VARCHAR2 NOT NULL,"
                        "Album INTEGER,"
                        "Artist INTEGER,"
                        "Genre INTEGER,"
                        "CONSTRAINT u_location UNIQUE (Location)"
                        "CONSTRAINT fk_Album foreign key (Album)"
                        " references Album,"
                        "CONSTRAINT fk_Artist foreign key (Artist)"
                        " references Artist,"
                        "CONSTRAINT fk_Genre foreign key (Genre)"
                        " references Genre,"
                        "CONSTRAINT fk_Recovery foreign key (Recovery)"
                        " references track)"
                    ))
            return false;
        if(!insertUnknow(progress, "INSERT INTO album"
                         " (name, year, cover, heart)"
                         " VALUES (\"Unknow\", -1, \"\", 0)"))
            return false;
        if(!insertUnknow(progress, "INSERT INTO Artist (name, heart)"
                         " VALUES (\"Unknow\", 0)"))
            return false;
        if(!insertUnknow(progress, "INSERT INTO genre (name)"
                         " VALUES (\"Unknow\")"))
            return false;
        progress->stop();
        return true;
    }
    return false;
}

bool Connection::insertUnknow(WProgressBar *progress,
                              const QString & cmd)
{
    QSqlQuery query;
    bool ret = false;
    progress->progress();
    ret = query.exec(cmd);
    progress->progress();
    query.finish();
    qDebug() << dbQueryStr << cmd;
    if(!ret)
    {
        qWarning() << dbFailedStr << cmd;
        FileHandler rm;
        db.close();
       /* rm.removeFile(dbFileNameStr);*/
    }
    return ret;
}

bool Connection::createTable(WProgressBar *progress,
                             const QString & cmd)
{
    QSqlQuery query;
    bool ret = false;
    progress->progress();
    ret = query.exec(cmd);
    progress->progress();
    query.finish();
    qDebug() << dbQueryStr << cmd;
    if(!ret)
    {
        qWarning() << dbFailedStr;
        FileHandler rm;
        db.close();
        rm.removeFile(dbFileNameStr);
    }
    return ret;
}

bool Connection::isConnected()
{
   return db.isOpen();
}
